<template>
  <div class="layout">
    <Layout>
      <Header :style="{position: 'fixed', width: '100%', zIndex: 9999}" class="layout-header">
        <div unselectable="on" onselectstart="return false;" style="-moz-user-select:none;">
          <Menu mode="horizontal" @on-select="handleSelect" @on-open-change="handleOpen">
            <div class="layout-logo">
              <Icon type="ios-create"/>
              脚本编辑器
            </div>
            <MenuItem name="run">
              <Icon type="ios-navigate"></Icon>
              运行
            </MenuItem>
            <MenuItem name="save">
              <Icon type="ios-keypad"></Icon>
              保存
            </MenuItem>
            <MenuItem name="beautify">
              <Icon type="ios-analytics"></Icon>
              格式化
            </MenuItem>
            <MenuItem name="remove">
              <Icon type="ios-paper"></Icon>
              清空控制台
            </MenuItem>
            <Submenu name="insert">
              <template slot="title">
                <Icon type="logo-javascript" />
                插入函数
              </template>
              <template v-for="(item, key) in functionList">
                <Tooltip placement="right" :transfer="true" theme="light" :key="key" max-width="300" v-if="isTipShow">
                  <div slot="content">
                      <p class="func-title">
                        <Icon type="logo-foursquare" />{{item.name}}</p>
                      <p class="tip-title">函数说明</p>
                      <p class="tip-content" v-html="item.explain"></p>
                      <p class="tip-title">使用示例</p>
                      <p class="tip-content" v-html="item.example"></p>
                  </div>
                  <MenuItem :name="`${item.name}-func-${item.instance}`">{{item.name}}</MenuItem>
                </Tooltip>
              </template>
          </Submenu>
          </Menu>
        </div>
      </Header>
      <Content>
        <Split v-model="split1">
          <div slot="left" class="split-pane">
            <div class="search-input" v-if="isSearch">
              <Input ref="input" v-model="searchValue" @on-change="onChangeSearch" placeholder="请输入搜索内容" size="small" style="width: 250px">
                <span slot="append">
                  <Icon type="ios-arrow-up" @click="handleLast" :style="{color: searchCur <= 1 ? '#ccc' : ''}"/>
                  <Divider type="vertical" />
                  <Icon type="ios-arrow-down" @click="handleNext" :style="{color: searchCur == searchNum ? '#ccc' : ''}"/>
                  <Divider type="vertical" />
                  <Icon type="md-close" @click="isSearch = false"/>
                </span>
              </Input>
              <span class="search-num">{{searchCur}}/{{searchNum}}</span>
            </div>
            <editor
                v-model="code"
                :options="option"
                height="100%"
                lang="javascript"
                theme="chrome"
                width="100%"
                @init="editorInit"
            />
          </div>
          <div slot="right" class="split-pane split-pane-right">
            <div class="consoleLog">
              <template v-for="(item, key) in MessageList">
                <div :class="item[0]" :key="key"> &gt; {{ item[1] }}</div>
              </template>
            </div>
          </div>
        </Split>
      </Content>
    </Layout>
  </div>
</template>
<script>
import editor from "vue2-ace-editor";
import beautify from "beautify";
import { functionList } from '../utils/funcList'

const GetQueryString = (n) => {
  var fn = (name, type) => {
    let target
    if (type === 'hash') {
      target = window.location.hash.split('?')[1]
    } else {
      target = window.location.search.substr(1)
    }
    if (!target) {
      return null
    }
    let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
    let r = target.match(reg)
    if (r != null) {
      return r[2]
    }
    return null
  }
  return fn(n) || fn(n, 'hash')
}

export default {
  components: {
    editor
  },
  data() {
    return {
      code: '',
      split1: 0.5,
      title: '脚本编辑器',
      MessageList: [],
      option: {
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true
      },
      isSearch: false,
      searchValue: '',
      searchNum: 0,
      searchCur: 0,
      isTipShow: true,
      functionList
    }
  },
  /**
   * 页面创建时
   * @return {[type]} [description]
   */
  created() {
    let that = this
    window.openXlg = function (xlg) {
      that.$refs.iframe.contentWindow.postMessage({
        xlg
      }, '*') 
    }
    // 本地联调
    if (process.env.NODE_ENV !== 'production') {
      window.xlgData = {}
      let params = '?name=财务逾期债权&gongQiFileId=a0f4c0b75f36480cad042b68a54f663e&domain=MIX'
      let url = 'http://' + location.host + params
      window.history.replaceState({
        path: url
      }, '', url);
      localStorage.setItem('userId', 'admin')
      localStorage.setItem('userToken', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInByb2plY3QiOiJnb25ncWlfYm9vdF9AMjAyNSIsImlhdCI6MTY2OTg1NzY1NSwidXNlcm5hbWUiOiJhZG1pbiJ9.WB7aJEBaP5Gn1YF4NLrt2TvnmDMkRXYD7NNzuGTrog4')
    }
    this._listenEvent()
  },
  computed: {
    fileType() {
      return GetQueryString("fileType");
    },
    gongQiFileId() {
      return GetQueryString('gongQiFileId')
    }
  },
  mounted() {
    setTimeout(() => {
      console.log("初始化加载", this.gongQiFileId)
      if (this.gongQiFileId) {
        this.handleLoad();
      }
    }, 300)
  },
  methods: {
    /**
     * 监听键盘事件
     */
    _listenEvent() {
      console.log('【designerKey】监听键盘事件')
      const _this = this
      // 监听按键按下
      document.onkeydown = function (event) {
        const e = event || window.event
        const code = e.code
        console.log('==============>code',code)
        if (e.ctrlKey) {
          switch (code) {
            case 'KeyS': // S 保存
              console.log('【designerKey】保存')
              e.preventDefault()
              _this.handleSave()
              break
            case 'KeyF': // F 搜索
              e.preventDefault()
              _this.searchValue = ''
              _this.isSearch = true
              _this.$nextTick(() => {
                _this.$refs.input.focus()
              })
              break
          }
        }
      }
    },
    /**
     * 取消监听键盘事件
     */
    _offListenEvent() {
      console.log('【designerKey】取消监听键盘事件')
      document.onkeydown = null
      document.onkeyup = null
      document.onmousewheel = null
      document.onmousedown = null
      document.onmouseup = null
      document.onmousemove = null
      window.removeEventListener('mousewheel', null)
    },
    editorInit: function (editor) {
      require("brace/ext/language_tools"); // language extension prerequsite...
      require("brace/mode/html");
      require("brace/mode/javascript"); // language
      require("brace/mode/less");
      require("brace/theme/chrome");
      require("brace/snippets/javascript"); // snippet
      delete editor.keyBinding.$defaultHandler.commandKeyBinding['ctrl-f'] // 取消编辑器自带的ctrl-f监听
      this.editor = editor
    },
    onChangeSearch () {
      setTimeout(() => {
        this.searchNum = this.editor.findAll(this.searchValue, {
          backwards: false, // 是否从当前光标所在的位置向后搜索
          wrap: true, // 当搜索到达结尾时，是否将搜索返回到开头
          caseSensitive: false, // 搜索是否应该区分大小写
          wholeWord: false, // 搜索是否只匹配整个单词
          regExp: false // 搜索是否为正则表达式
        });
        this.searchCur = this.searchNum ? 1 : 0
        if (this.searchValue.length === 0) {
          this.searchNum = 0
          this.searchCur = 0
        }
      }, 500);
    },
    handleNext () {
      if (this.searchCur < this.searchNum) {
        this.searchCur ++
        this.editor.findNext()
      }
    },
    handleLast () {
      if (this.searchCur > 1) {
        this.searchCur --
        this.editor.findPrevious()
      }
    },
    handleLoad() {
      if (this.gongQiFileId) {
        this.$request({
          url: "/web/apps/gongqi.tool.jsEditor/jsEditor/openJS",
          method: "GET",
          params: {
            gongqiFileId: this.gongQiFileId
          }
        }).then(data => {
          if (data.code === 200) {
            let result = JSON.parse(data.result)
            this.title = result.title
            this.code = result.content
          }
        }).catch(error => {
          console.log("error", error)
        })
      }
    },
    handleSelect(name) {
      if (name === 'beautify') {
        this.handleBeautify();
      }
      if (name === 'run') {
        this.handleRun();
      }
      if (name === 'save') {
        this.handleSave();
      }
      if (name === 'remove') {
        MessageList = []
        this.MessageList = []
      }
      if (name.indexOf('-func') !== -1) {
        let example = name.split('-')[2]
        this.editor.insert(example) // 在光标处插入
        setTimeout(() => {
          this.isTipShow = false
        }, 200)
      }
    },
    handleBeautify() {
      this.code = beautify(this.code, {format: "js"})
    },
    handleSave() {
      if (this.gongQiFileId) {
        this.$request({
          url: `/web/apps/gongqi.tool.jsEditor/jsEditor/saveJS?gongqiFileId=${this.gongQiFileId}`,
          method: "POST",
          data: {
            title: this.title,
            content: this.code
          }
        }).then(data => {
          console.log("data", data)
          this.$Message.success('保存成功');
        }).catch(error => {
          console.log("error", error)
          this.$Message.info('保存失败');
        })
      } else {
        // 新建js文件保存
        window.parent.window.saveFile('.js', this.code, null, null, null, null, null)
      }
    },
    async handleRun() {
      try {
        const layer = window.parent.window.layer;
        if (layer) {
          layer.msg("代码开始执行", {zIndex: layer.zIndex})
        }
        this.MessageList = MessageList;
        // loading加载弹窗
        this.$Spin.show({
          render: (h) => {
            return h('div', [
              h('Icon', {
                'class': 'demo-spin-icon-load',
                props: {
                  type: 'ios-loading',
                  size: 18
                }
              }),
              h('div', '运行中')
            ])
          }
        });
        await $codeRun(this.code)
        this.$Spin.hide();
      } catch (error) {
        this.$Spin.hide();
        console.log("代码执行错误", error.message)
        if (window.parent) {
          setTimeout(() => {
            window.MessageList.push(['err', error.message])
            let msg = error.message.split(':')[1] ? error.message.split(':')[1] : '代码执行失败'
            const layer = window.parent.window.layer;
            if (layer) {
              layer.msg(msg, {zIndex: layer.zIndex})
              window.MessageList.push(['err', '代码执行失败'])
            }
          }, 1200)
        }
      }
    },
    handleOpen () {
      this.isTipShow = true
    }
  }
}
</script>

<style lang="scss">
.layout {
  position: relative;
  overflow: hidden;

  .layout-logo {
    width: 120px;
    height: 42px;
    font-size: 16px;
    font-weight: bold;
    float: left;
    position: relative;
  }

  .layout-nav {
    width: 420px;
    margin: 0 auto;
    margin-right: 20px;
  }

  .layout-header {
    background: #FFFFFF;
    color: white;
    height: 42px;
    line-height: 42px;

    .ivu-menu-horizontal {
      height: 42px;
      line-height: 42px;
    }

    .ivu-menu-horizontal.ivu-menu-light:after {
      display: none;
    }
  }

  .ivu-layout-content {
    height: calc(100vh - 42px);
    margin-top: 42px;
  }
}


.layout-footer-center {
  text-align: center;
}

.dev-run-preview .dev-run-preview-edit {
  display: none
}

.split-pane {
  height: 100%;
  position: relative;
}

.split-pane-right {
  padding: 10px;
  height: 100%;
  overflow: hidden;
  overflow-y: scroll;

  .consoleLog {
    word-wrap: break-word;
    color: #848484;
    font-size: 12px;
    font-family: "Lato", "Helvetica Neue", "Arial", "Verdana", "Tahoma", "Lucida Sans", "FreeSans", "Lucida Sans Unicode", "Luxi Sans", sans-serif;
    user-select: text;

    > div {
      margin: 2px;
      padding: 5px;
    }

    .info {
      color: blue;
      BACKGROUND: #ffefef;
      width: 100%;
    }

    .log {
      BACKGROUND: #ffefef;
      width: 100%;
    }

    .err {
      color: #ca0000;
      BACKGROUND: #ffefef;
      width: 100%;
    }
  }
}

.demo-spin-icon-load{
  animation: ani-demo-spin 1s linear infinite;
}

.ivu-spin-fix {
  background-color: rgba(255,255,255,.3) !important;
}

.ace_gutter-cell.ace_error {
  background-image: none !important;
}

.search-input {
  position: absolute !important;
  right: 15px;
  top: 0;
  z-index: 999;
  i {
    cursor: pointer;
  }
  .ivu-input {
    font-size: 12px;
  }
}
.search-num {
  position: absolute;
  right: 100px;
  top: 3px;
  color: #ccc;
  z-index: 9999;
  font-size: 12px;
}

.ivu-tooltip-popper {
  z-index: 99999 !important;
  transform: translateX(15px);
}
.ivu-tooltip {
  width: 100%;
}
.func-title {
  text-align: center;
  font-weight: bold;
}
.tip-title {
  font-weight: bold;
  font-size: 13px;
}
.tip-content {
  padding-left: 10px;
  font-size: 12px;
}
.ivu-select-dropdown {
  max-height: 500px !important;
}
</style>
